import { useRef, useState } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';

import { useRequest } from 'ahooks';
import { Button, Checkbox, Form, Input, message } from 'antd';

import Captcha, { CaptchaRef } from '@/components/captcha';
import CodeInput from '@/components/code-input';

import { store } from '@/store';

import { emailReg, mobileReg } from '@/config/rule';
import { ClientType, LoginType } from '@/enum';
import { securityLogin, securityPublicKey } from '@/services/base/denglumokuaidenglujiekou';
import {
  codeSendEmailCode,
  codeSendMobileCode
} from '@/services/base/yanzhengmamokuaifasongyanzhengmajiekou';
import { request } from '@/utils/api';
import { encryptRSA } from '@/utils/encrypt';

import Panel from '../panel';

type FormValues = {
  username: string;
  password: string;
  saveLogin: boolean;
};

const Page: React.FC = () => {
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();
  const [form] = Form.useForm();
  const captcha = useRef<CaptchaRef>(null);
  const [loginType, setLoginType] = useState(LoginType.password);
  const login = useRequest(
    async (query: FormValues, captchaVerification: string) => {
      // 获取公钥后RSA算法加密密码
      const password = await encryptRSA(query.password, async () => {
        const res = await securityPublicKey();

        return res?.data;
      });

      const formatQuery = {
        loginType,
        clientType: ClientType.web,
        ...query,
        password,
        captchaVerification
      } as Record<string, any>;

      if (loginType === LoginType.email) {
        formatQuery.email = formatQuery.username;
        formatQuery.code = formatQuery.emailCode;
        delete formatQuery.emailCode;
        delete formatQuery.username;
        delete formatQuery.password;
      } else if (loginType === LoginType.mobile) {
        formatQuery.mobile = formatQuery.username;
        formatQuery.code = formatQuery.mobileCode;
        delete formatQuery.mobileCode;
        delete formatQuery.username;
        delete formatQuery.password;
      }

      const token = await securityLogin(
        formatQuery as unknown as ArgumentsType<typeof securityLogin>[0]
      );

      if (!token.data) {
        message.error('登录失败，请检查账号密码是否正确');

        return;
      }

      const userInfo = await store.getUserInfoByToken(token.data);

      if (!userInfo) {
        message.error('登录失败，请联系管理员');

        return;
      }

      // 设置token
      request.defaults.headers.token = request.defaults.headers.token || token.data;
      // 缓存token
      localStorage.setItem('token', token.data);

      setTimeout(() => {
        const redirect = searchParams.get('redirect') || '/';
        navigate(redirect);
      }, 300);

      return token.data;
    },
    {
      manual: true
    }
  );
  // 是否获取邮箱验证码成功
  const codeEmailSuccess = useRef(false);
  // 是否获取手机验证码成功
  const codeMobileSuccess = useRef(false);
  // 获取邮箱验证码时的拖拽校验
  const emailCaptchaVerification = useRef('');
  // 获取手机验证码时的拖拽校验
  const mobileCaptchaVerification = useRef('');

  const onFinish: React.ComponentProps<typeof Form<FormValues>>['onFinish'] = async (values) => {
    if (loginType === LoginType.email) {
      if (!codeEmailSuccess.current) {
        store.app?.message.info('请先获取验证码');

        return;
      }

      login.run(values, emailCaptchaVerification.current);

      return;
    }

    if (loginType === LoginType.mobile) {
      if (!codeMobileSuccess.current) {
        store.app?.message.info('请先获取验证码');

        return;
      }

      login.run(values, mobileCaptchaVerification.current);

      return;
    }

    // login.run(values, 'res.data.id')
    captcha.current?.open({
      validSuccess(res) {
        login.run(values, res.data.id);
      }
    });
  };

  return (
    <>
      <Panel
        title={import.meta.env.VITE_TITLE}
        // corner={{
        //   to: '/user/forget',
        //   children: '找回密码'
        // }}
      >
        <Panel.Tabs
          items={[
            { label: '密码登录', value: LoginType.password }
            // { label: '邮箱登录', value: LoginType.email },
            // { label: '手机号登录', value: LoginType.mobile },
          ]}
          value={loginType}
          onChange={setLoginType}
        />

        <Form<FormValues>
          form={form}
          onFinish={onFinish}
          size="large"
          variant="filled"
          disabled={login.loading}
          initialValues={{
            saveLogin: false
          }}
        >
          <Form.Item name="username" rules={[{ required: true, message: '请输入账号' }]}>
            <Input
              placeholder={
                {
                  [LoginType.password]: '请输入账号',
                  [LoginType.email]: '请输入邮箱地址',
                  [LoginType.mobile]: '请输入手机号'
                }[loginType]
              }
              allowClear
            />
          </Form.Item>

          {loginType === LoginType.password && (
            <>
              <Form.Item name="password" rules={[{ required: true, message: '请输入密码' }]}>
                <Input.Password placeholder="请输入账号密码" allowClear />
              </Form.Item>
            </>
          )}

          <Form.Item dependencies={['username']} noStyle>
            {({ getFieldValue }) => {
              const isMobile = mobileReg.test(getFieldValue('username'));
              const isEmail = emailReg.test(getFieldValue('username'));

              return (
                <>
                  <Form.Item
                    name="emailCode"
                    rules={[{ required: loginType === LoginType.email, message: '请输入验证码' }]}
                    style={{
                      display: loginType === LoginType.email ? undefined : 'none'
                    }}
                  >
                    <CodeInput
                      getCode={async (captcha) => {
                        emailCaptchaVerification.current = captcha;
                        const { username: email } = await form.validateFields(['username']);

                        await codeSendEmailCode({ email });
                      }}
                      onCodeSuccess={() => {
                        codeEmailSuccess.current = true;
                      }}
                      placeholder="请输入验证码"
                      allowClear
                      buttonDisabled={!isEmail}
                    />
                  </Form.Item>

                  <Form.Item
                    name="mobileCode"
                    rules={[{ required: loginType === LoginType.mobile, message: '请输入验证码' }]}
                    style={{
                      display: loginType === LoginType.mobile ? undefined : 'none'
                    }}
                  >
                    <CodeInput
                      getCode={async (captcha) => {
                        mobileCaptchaVerification.current = captcha;
                        const { username: mobile } = await form.validateFields(['username']);

                        await codeSendMobileCode({ mobile });
                      }}
                      onCodeSuccess={() => {
                        codeMobileSuccess.current = true;
                      }}
                      placeholder="请输入验证码"
                      allowClear
                      buttonDisabled={!isMobile}
                    />
                  </Form.Item>
                </>
              );
            }}
          </Form.Item>

          <Form.Item name="saveLogin" valuePropName="checked">
            <Checkbox>7天内免登录</Checkbox>
          </Form.Item>

          <Button htmlType="submit" type="primary" block loading={login.loading}>
            登录
          </Button>
        </Form>
      </Panel>

      <Captcha ref={captcha} />
    </>
  );
};

export default Page;
